/**************************************************************************//**
 * @item     CosyOS-II Config
 * @file     mcucfg_cmx.h
 * @brief    CMSIS Cortex-M Core Config File
 * @author   迟凯峰
 * @version  V3.4.0
 * @date     2025.01.06
 ******************************************************************************/

#ifndef __MCUCFG_CMX_H
#define __MCUCFG_CMX_H

///////////////////////////////////////////////////////////////////////////////

          //*** <<< Use Configuration Wizard in Context Menu >>> ***//

///////////////////////////////////////////////////////////////////////////////
// <h> 编译器配置
// <i> 编译器配置

// <q> 是否屏蔽编译器警告？
// <i> 部分内核服务会引起编译器警告，但这并不会导致运行错误，您是否希望屏蔽这些警告？
#define __MCUCFG_WARNINGDISABLE         1

// </h>
///////////////////////////////////////////////////////////////////////////////
// <h> 任务栈配置
// <i> 任务栈配置最小值：
// <i> 未启用浮点寄存器上下文自动保存：64Bytes；
// <i> 已启用浮点寄存器上下文自动保存：200Bytes。

// <o> 系统启动任务的任务栈大小（Bytes）
#define MCUCFG_STACKSIZE_STARTER        512

// <o> 系统空闲任务的任务栈大小（Bytes）
#define MCUCFG_STACKSIZE_SYSIDLE        256

// </h>
///////////////////////////////////////////////////////////////////////////////
// <o> 系统中断配置
// <0=> SysTick_Handler + PendSV_Handler <1=> TIMn_IRQHandler + XXX_IRQHandler

// <i> SysTick_Handler + PendSV_Handler：
// <i> 要求MCU必须有BASEPRI寄存器，同时您不能调用xMaskingPRI和xResumePRI进出全局临界区，也不允许私自使用BASEPRI寄存器。
// <i> 如Cortex-M0/M0+/M23等内核，都没有BASEPRI寄存器，就不能采用此方案。
// <i> 又如虽使用了Cortex-M3/M4/M33/M7等内核，但确想调用xMaskingPRI和xResumePRI来实现不同掩蔽范围的全局临界区保护，也不能采用此方案。

// <i> TIMn_IRQHandler + XXX_IRQHandler：
// <i> 用TIMn替代SysTick，TIMn_IRQHandler替代SysTick_Handler，XXX_IRQHandler替代PendSV_Handler。
// <i> CosyOS将不会使用PendSV_Handler和BASEPRI寄存器，如果MCU有BASEPRI寄存器，您可调用xMaskingPRI和xResumePRI进出全局临界区。
// <i> 但仍会使用SysTick定时器，用于任务管理器的时间统计。
// <i> 采用此方案，需在文本编辑界面中配置下方的用户定义项。
// <i> TIMn_IRQHandler 与 XXX_IRQHandler 必须满足如下关系：TIMn_IRQn / 32 == XXX_IRQn / 32。
// <i> 下方的用户定义项已经给出示例：TIM14_IRQHandler + EXTI0_1_IRQHandler，对于Cortex-M0/M0+，直接可用。
#define MCUCFG_SYSINT                   0

#if MCUCFG_SYSINT

// 1、PendSV_Handler替代中断-名称
#define OS_PendSV_Handler               EXTI0_1_IRQHandler

// 2、PendSV_Handler替代中断-向量号
#define MCUCFG_PENDSVIRQ                EXTI0_1_IRQn

// 3、SysTick_Handler替代中断-名称
#define OS_SysTick_Handler              TIM14_IRQHandler

// 4、SysTick_Handler替代中断-向量号
#define MCUCFG_SYSTICKIRQ               TIM14_IRQn

// 5、SysTick_Handler替代中断-中断清零（清中断标志位）
#define mSysTick_Clear                  TIM14->SR = 0

// 6、SysTick的替代定时器-配置
#define mSysTick2_INIT \
do{ \
	/* 定时器中断的优先级，系统根据中断向量号自动配置为最低级 */ \
	mSysTick2_Priority; \
	/* 定时器时钟使能 */ \
	RCC->APB1ENR |= RCC_APB1ENR_TIM14EN; \
	/* 预分频，本示例，APB1CLK = HCLK / 1 */ \
	TIM14->PSC = (SYSCFG_SYSCLK / 1000000) / 1 * 1 - 1; \
	/* 重装载值 */ \
	TIM14->ARR = SYSCFG_SYSTICKCYCLE - 1; \
	/* 使能计数器 | 只有上溢/下溢会生成更新中断 | 计数方向任意 */ \
	TIM14->CR1 = (1 << 0) | (1 << 2); \
	/* 使能更新中断 */ \
	TIM14->DIER = 1; \
}while(false)

// 7、MCU是否有BASEPRI寄存器？(0：无，1：有)
#define MCUCFG_BASEPRI_USED             0

#endif
///////////////////////////////////////////////////////////////////////////////
// <o> PendSV_FIFO互斥访问方案
// <1=> 互斥访问指令 <2=> 互斥访问机制 <3=> 关闭总中断

// <i> 方案一、互斥访问指令
// <i> 该方案仅适用于Cortex-M3/M4/M7等支持互斥访问指令[LDREX/STREX]的内核，可实现全局不关总中断、零中断延迟。

// <i> 方案二、互斥访问机制
// <i> 该方案适用于所有ARM内核，可实现全局不关总中断、零中断延迟。
// <i> 注意事项：
// <i> 1、编译器可能需要开启对GNU/GCC的支持（Keil MDK不用）。
// <i> 2、凡是调用了中断挂起服务_FIFO的中断函数，都必须在函数外部上方声明全局寄存器变量r7，以通知编译器该中断函数不可使用r7。
// <i> 自动声明：
// <i> 为提高易用性，系统默认已为用户配置为自动声明（见下方）。但自动声明的作用域是全局的，这会导致大部分函数都将无法使用r7。
// <i> 手动声明：
// <i> 为了追求更好的性能，您可采用手动声明。手动声明首先要注释掉下方的全局寄存器变量声明，
// <i> 而后可以把所有调用了中断挂起服务_FIFO的中断函数，统一放在一个C文件里，并在该文件中一次性声明全局寄存器变量r7。

// <i> 方案三、关闭总中断
// <i> 该方案适用于所有ARM内核，并具有极短的、确定的关闭总中断时间（包括再次开启总中断在内，不超过10个指令周期）。
// <i> 该方案，内核关闭总中断仅发生在中断挂起服务装载器中的__LOAD段。

#define MCUCFG_PENDSVFIFO_MUTEX         1

/* 自动声明全局寄存器变量r7（若采用手动声明，需注释掉下方的声明）*/
#if MCUCFG_PENDSVFIFO_MUTEX == 2
register void **mPendSV_FIFO_Rx __ASM("r7");
#endif

///////////////////////////////////////////////////////////////////////////////
// <o> PendSV_FIFO深度
// <i> 此项参数取决于您在中断中调用的挂起服务_FIFO的总数及中断的频率。
// <i> 对于Cortex-M来说，PendSV_FIFO的最大深度定义为255。
// <i> 可开启PendSV_FIFO监控功能，监控历史上的最大值，再适当增大，以确保其不会溢出。
#define MCUCFG_PENDSVFIFO_DEPTH         64

///////////////////////////////////////////////////////////////////////////////
// <q> 浮点寄存器上下文自动保存
// <i> 是否启用浮点寄存器的上下文自动保存功能？
// <i> 如果启用了硬件浮点单元，并且在多个任务或中断中都要进行浮点运算，应该开启该功能；
// <i> 如果仅在特定的一个任务或中断中进行浮点运算，可以关闭该功能以提高性能。
#define __MCUCFG_ASPEN_LSPEN            0

///////////////////////////////////////////////////////////////////////////////
// <o> 系统滴答时钟源
// <0=> 外部时钟 <1=> 内核时钟
// <i> 在此配置系统滴答时钟源，您无需再额外配置。
// <i> 如果您使用了外部晶振且系统时钟为8的整数倍，可配置系统滴答时钟源为外部时钟，以提高系统滴答的精度。
#define MCUCFG_SYSTICKCLKSOURCE         1

///////////////////////////////////////////////////////////////////////////////

                //*** <<< end of configuration section >>> ***//

///////////////////////////////////////////////////////////////////////////////

#if __FPU_PRESENT == __ENABLED__ && __FPU_USED == __ENABLED__
#define MCUCFG_HARDWAREFPU  __ENABLED__
#define MCUCFG_ASPEN_LSPEN  __MCUCFG_ASPEN_LSPEN
#else
#define MCUCFG_HARDWAREFPU  __DISABLED__
#define MCUCFG_ASPEN_LSPEN  __DISABLED__
#endif

#if MCUCFG_SYSINT
#if MCUCFG_PENDSVIRQ / 32 != MCUCFG_SYSTICKIRQ / 32
#error MCUCFG_PENDSVIRQ / 32 != MCUCFG_SYSTICKIRQ / 32
#endif
#else
#define OS_PendSV_Handler               PendSV_Handler
#define OS_SysTick_Handler              SysTick_Handler
#define mSysTick_Clear
#endif

#if MCUCFG_PENDSVFIFO_DEPTH > 255
#error 中断挂起服务FIFO队列深度值溢出！
#endif



#endif
